package com.uni.util;


import com.uni.entity.ShopUser;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.*;
import java.security.PrivateKey;
import java.security.PublicKey;


/**
 *  JWT 的工具类：包含了创建和解码的工具
 */
@Slf4j
public class JWTUtils {

    /**
     * 私钥加密token
     * @param user 载荷数据
     * @param privateKey 私钥
     * @param expireMinutes 过期时间,单位分钟
     * @return
     */
    public static String generateToken(ShopUser user, PrivateKey privateKey, Integer expireMinutes) throws Exception{

        return Jwts.builder()
                .claim(JWTConstants.JWT_KEY_ID, user.getId())
                .claim(JWTConstants.JWT_KEY_USER_NAME, user.getUserName())
                .claim(JWTConstants.JWT_KEY_ROLE, user.getRole())
                .setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate())
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    }

    /**
     * 私钥加密token
     * @param user 载荷数据
     * @param privateKey 私钥字节数组
     * @param expireMinutes 过期时间,单位分钟
     * @return
     */
    public static String generateToken(ShopUser user, byte[] privateKey, Integer expireMinutes) throws Exception{

        return Jwts.builder()
                .claim(JWTConstants.JWT_KEY_ID, user.getId())
                .claim(JWTConstants.JWT_KEY_USER_NAME, user.getUserName())
                .claim(JWTConstants.JWT_KEY_ROLE, user.getRole())
                .setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate())
                .signWith(SignatureAlgorithm.RS256, RsaUtils.getPrivateKey(privateKey))
                .compact();
    }

    /**
     * 使用公钥解析token
     * @param token 用户请求中的token
     * @param publicKey 公钥对象
     * @return
     */
    public static Jws<Claims> parserToken(String token, PublicKey publicKey){
        return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
    }

    /**
     * 公钥解析token
     * @param token 用户请求中的token
     * @param publicKey 公钥字节数组
     * @return
     * @throws Exception
     */
    private static Jws<Claims> parserToken(String token, byte[] publicKey) throws Exception {
        return Jwts.parser().setSigningKey(RsaUtils.getPublicKey(publicKey))
                .parseClaimsJws(token);
    }

    /**
     * 获取token中的用户信息
     * @param token 用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     * @throws Exception
     */
    public static ShopUser getInfoFromToken(String token, PublicKey publicKey) throws Exception {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();

        Long user_id = (Long) body.get(JWTConstants.JWT_KEY_ID);
        String user_name = (String) body.get(JWTConstants.JWT_KEY_USER_NAME);
        Integer user_role = (Integer) body.get(JWTConstants.JWT_KEY_ROLE);
        return new ShopUser(user_id, user_name, user_role);
    }

    /**
     * 获取token中的用户信息
     * @param token 用户请求中的token
     * @param publicKey 公钥字节数组
     * @return 用户信息
     * @throws Exception
     */
    public static ShopUser getInfoFromToken(String token, byte[] publicKey) throws Exception {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();

        Long user_id = (Long) body.get(JWTConstants.JWT_KEY_ID);
        String user_name = (String) body.get(JWTConstants.JWT_KEY_USER_NAME);
        Integer user_role = (Integer) body.get(JWTConstants.JWT_KEY_ROLE);
        return new ShopUser(user_id, user_name, user_role);
    }


    public static void main(String[] args) throws Exception {
//        PublicKey publicKey = RsaUtils.getPublicKey("D://rsa//rsa.pub");
//        Jws<Claims> claimsJws = parserToken("eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX2lkIjoxMjczOTEyMTE1MDI3MTE2MDMyLCJ1c2VyX3JvbGUiOjAsImV4cCI6MTU5MzMxODM2OH0.FqXgDP6b3qoTrAXteCHxQ2IUnryh_7XfeUHPTW8bXiLpXVDn1zigBJTGcxFhivcy0aIACBs32i0ynbBc5DUli6chesvIE7HfbAl9IiBj0D6Ujde-HnQdHcrzjPt783fy-5Voj4HJZWHrAH9SCPkKqs6VUUR6Ba8QHJeoJtkmUXg", publicKey);
//        System.out.println(claimsJws.getSignature());
//        System.out.println(claimsJws.toString());
    }

}
